//
//  KBTool.swift
//  Keyboard
//
//  Created by tucici on 2023/3/3.
//

import UIKit
import ZLPhotoBrowser


func MyPrint<T>(_ msg:T,file:String = #file, funcName:String = #function, lineNumber:Int = #line){
    let fileName = (file as NSString).lastPathComponent
    let formmater = DateFormatter()
    formmater.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS"
    let time =  formmater.string(from:Date())
    print("\(fileName)(\(lineNumber))-\(time):\(msg)")
}

class KBTool: NSObject {
    ///返回日期时间的16进制
    class func dateHex(_ stamp:Int)->(date:String,week:String){
        let date = NSDate.dateOfStamp(stamp)
        let week = date.weekday! >= 2 ? date.weekday! - 1 : 7
        let yearStr = "\(date.year!)".toHex().fix(4, "0") as String
        let monthStr = "\(date.month!)".toHex().fix(2, "0") as String
        let dayStr = "\(date.day!)".toHex().fix(2, "0") as String
        let hourStr = "\(date.hour!)".toHex().fix(2, "0") as String
        let minStr = "\(date.minute!)".toHex().fix(2, "0") as String
        let secStr = "\(date.second!)".toHex().fix(2, "0") as String
        let weekStr = "\(week)".toHex().fix(2, "0") as String
        return(date:yearStr+monthStr+dayStr+hourStr+minStr+secStr,week:weekStr)
    }
    
    ///BIN转string
    class func binToString(_ name:String)->String{
        let path = Bundle.main.url(forResource: name, withExtension: "bin")
        let data = try! Data(contentsOf: path!)
        return dataToString(data)
    }
    ///data 转string
    class func dataToString(_ data:Data)->String{
        let bytes = [UInt8](data)
        var string = ""
        for byte in bytes{
            string += String(format: "%.2X", byte)
        }
        return string
    }
    
    ///大端字符串，转 小端字符串
    class func reverse(_ str:String)->String{
        var resutl = ""
        var temp = ""
        var i = 0
        for s in str.reversed(){
            if i % 2 == 0 {
                temp  = String(s)
            }else{
                temp = String(s)+temp
                resutl += temp
            }
            i += 1
        }
        return resutl
    }
    
    /// 打开相机
    class func openCamera(_ block:(([Data]) -> Void)?){
        ZLPhotoConfiguration.default().cameraConfiguration.allowRecordVideo = false
        let camera = ZLCustomCamera()
        camera.takeDoneBlock = {(image, url) in
            guard let img = image else {return}
            let data = KBTool.redraw(img, img.size.width)
            block?([data])
        }
        self.currentVC().showDetailViewController(camera, sender: nil)
    }
    
    /// 打开相册
    class func openAblum(_ maxCount:Int, _ block:(([Data],[UIImage]) -> Void)?){
        let config = ZLPhotoConfiguration.default()
        config.cameraConfiguration.allowRecordVideo = false
        config.allowSelectGif = true
        config.allowEditImage = true
        config.allowEditVideo = true
        config.editImageConfiguration.clipRatios = [ZLImageClipRatio.init(title: "320 : 172", whRatio: 320.0 / 172.0)]
        config.canSelectAsset = { (asset) -> Bool in
            return true
        }
        config.maxSelectCount = maxCount
        config.noAuthorityCallback = { (type) in
            switch type {
            case .library:
                debugPrint("No library authority")
            case .camera:
                debugPrint("No camera authority")
            case .microphone:
                debugPrint("No microphone authority")
            }
        }
        let ac = ZLPhotoPreviewSheet(selectedAssets:[])
        ac.showPhotoLibrary(sender: self.currentVC())
        ac.selectImageBlock = { (array, Bool)in
            if array.count <= 0 {return}
            var imgs = [UIImage]()
            for model in array{
                ///如果选择的是UIImage
                if model.image.className == "UIImage"{
                    imgs.append(model.image)
                }else{ ///如果选择的是GIF，则进行抽帧
                    guard let temp = (model.image as UIImage).images else {return}
                    imgs = self.GIF(temp,maxCount)
                }
            }
            
            //裁剪
            var datas = [Data]()
            for img in imgs{
                let data = KBTool.redraw(img,img.size.width)
                datas.append(data)
            }
            block?(datas,imgs)
        }
        ac.cancelBlock = {
            debugPrint("cancel select")
        }
        ac.selectImageRequestErrorBlock = { (errorAssets, errorIndexs) in
            debugPrint("fetch error assets: \(errorAssets), error indexs: \(errorIndexs)")
        }
    }
    
    ///裁剪
    class func redraw(_ img:UIImage,_ width:CGFloat)->Data{
        let h = 172 / 320.0 * width
        let imgref = img.cgImage
        let rect = CGRect(x:0, y: (img.size.height-h)/2.0, width:width, height: h)
        let newimageref = imgref?.cropping(to: rect)
        let newImg = UIImage(cgImage: newimageref!)
        
        UIGraphicsBeginImageContext(CGSize(width:320, height:172))
        newImg.draw(in:CGRect(x:0, y: 0, width:320, height:172))
        let newImg2 = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImg2.createImageData(with:newImg2, writetype:1)
    }
    
    ///对GIF，进行抽帧
    class func GIF(_ array:[UIImage],_ max:Int)->[UIImage]{
        let adg = array.count <= max ? 1 : ceil(CGFloat(array.count) / CGFloat(max))
        var i = 0
        var imgs = [UIImage]()
        while (array.count > i){
            let img = array[i]
            imgs.append(img)
            i += Int(adg)
        }
        return imgs
    }
    
    ///手动插入CRC
    class func crc8Data(_ data : NSData)->NSData
    {
        let mutdata = NSMutableData.init(data:data as Data)
        var byes = [UInt8](data)
        for i in 1..<data.length
        {
            byes[0] = byes[0] ^ byes[i]
        }
        byes[0] = byes[0] & 0xff
        let resultData = NSData.init(bytes: byes, length:1)
        mutdata.append(resultData as Data)
        return mutdata
    }
    
    //MARK: - 扫描
    class func scanDevice(_ block:(([CBPeripheral])->Void)? = nil){
        BLE.scanWithOther = { peripheral in
            let product = String(format: "%.2x%.2x", peripheral.advertData[0],peripheral.advertData[1])
            return productName == product
        }
        BLE.scanWithServices = [BLEData.setConfig.service_uuidString]
        
        KBDevice.bg_findAllAsync(nil){result in
            let array_result = result as? [KBDevice]
            BLE.startScan { array in
                for per in array{
                    if per.mac.count >= 0{
                        let device = KBDevice()
                        device.mac = per.mac
                        device.uuid = per.identifier.uuidString
                        device.bg_saveOrUpdateAsync()
                    }else{
                        let temp = array_result?.filter{($0 ).uuid == per.identifier.uuidString}
                        let device = temp?.last
                        per.mac = (device!).mac
                    }
                }
                DispatchQueue.main.async {
                    block?(array)
                }
            }
        }
    }
    
    
}
